# Gitee项目一键部署工具 - PowerShell版
# 此脚本整合了项目的所有功能，专注于Gitee项目的部署

# 设置一些基础变量
$SERVER_PORT = 3000
$LOG_FILE = "deploy.log"

# 创建日志文件
if (-not (Test-Path $LOG_FILE)) {
    New-Item -Path $LOG_FILE -ItemType File -Force | Out-Null
}
Add-Content -Path $LOG_FILE -Value "$(Get-Date): 部署服务器启动"

# 检查是否安装了必要的软件
function Check-Dependencies {
    $dependencies = @("git")
    $missing = @()
    
    foreach ($dep in $dependencies) {
        if (-not (Get-Command $dep -ErrorAction SilentlyContinue)) {
            $missing += $dep
        }
    }
    
    if ($missing.Count -gt 0) {
        Write-Error "错误: 缺少以下依赖项: $($missing -join ', ')"
        Write-Host "请先安装这些依赖项再继续。"
        exit 1
    }
}

# 生成前端HTML内容
function Generate-FrontendHTML {
    $htmlContent = @'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Gitee项目一键部署</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #2c3e50;
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
        }
        input[type="text"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
            font-size: 16px;
        }
        .hint {
            color: #666;
            font-size: 0.9em;
            margin-top: 5px;
        }
        .path-info {
            background-color: #e9f7fe;
            padding: 10px 15px;
            border-radius: 4px;
            margin: 15px 0;
            font-size: 0.95em;
            color: #0277bd;
            border-left: 3px solid #03a9f4;
        }
        .btn {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 12px 20px;
            font-size: 16px;
            cursor: pointer;
            border-radius: 4px;
            width: 100%;
            transition: background-color 0.3s;
        }
        .btn:hover {
            background-color: #2980b9;
        }
        .btn:disabled {
            background-color: #95a5a6;
            cursor: not-allowed;
        }
        .status {
            margin-top: 20px;
            padding: 15px;
            border-radius: 4px;
            display: none;
        }
        .success {
            background-color: #d4edda;
            color: #155724;
        }
        .warning {
            background-color: #fff3cd;
            color: #856404;
        }
        .error {
            background-color: #f8d7da;
            color: #721c24;
        }
        pre {
            background-color: #f8f9fa;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin-top: 20px;
            border: 1px solid #ddd;
            white-space: pre-wrap;
        }
        .version {
            text-align: center;
            margin-top: 20px;
            font-size: 12px;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Gitee项目一键部署工具</h1>
        
        <div class="form-group">
            <label for="domain">域名:</label>
            <input type="text" id="domain" placeholder="例如: app.example.com (可选)" required>
            <div class="hint">如需配置域名访问，请输入完整域名</div>
        </div>
        
        <div class="form-group">
            <label for="gitrepo">Gitee 项目名:</label>
            <input type="text" id="gitrepo" placeholder="例如: username/repo-name 或 https://gitee.com/username/repo-name" required>
            <div class="hint">可以输入项目路径或完整URL，如有https://gitee.com前缀会自动处理</div>
        </div>
        
        <div class="path-info">
            注意: 项目将自动部署到 <strong>/projects/仓库名</strong> 目录下
        </div>
        
        <div class="form-group">
            <label for="command">运行命令:</label>
            <input type="text" id="command" placeholder="例如: npm install && npm start" required>
            <div class="hint">部署后要执行的命令</div>
        </div>
        
        <button class="btn" id="deployBtn">一键部署</button>
        
        <div class="status" id="status"></div>
        <pre id="output"></pre>
        
        <div class="version">Gitee项目部署工具 v1.0</div>
    </div>

    <script>
        document.getElementById('deployBtn').addEventListener('click', function() {
            const domain = document.getElementById('domain').value.trim();
            const gitrepo = document.getElementById('gitrepo').value.trim();
            const command = document.getElementById('command').value.trim();
            
            // 验证输入
            if (!gitrepo || !command) {
                showStatus('请填写Gitee项目和运行命令', false);
                return;
            }
            
            // 显示正在部署状态
            showStatus('正在部署，请稍候...', true);
            document.getElementById('deployBtn').disabled = true;
            
            // 发送部署请求
            fetch('/deploy', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    domain: domain,
                    gitrepo: gitrepo,
                    command: command
                })
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                return response.json();
            })
            .then(data => {
                if (data.success) {
                    let successMsg = '部署成功!';
                    
                    // 显示项目路径
                    if (data.project_path) {
                        successMsg += ` 项目已部署到 ${data.project_path}`;
                    }
                    
                    showStatus(successMsg, true);
                    document.getElementById('output').textContent = data.output;
                } else {
                    showStatus('部署失败: ' + (data.error || '未知错误'), false);
                    document.getElementById('output').textContent = data.output || '';
                }
            })
            .catch(error => {
                showStatus('请求错误: ' + error.message, false);
            })
            .finally(() => {
                document.getElementById('deployBtn').disabled = false;
            });
        });
        
        function showStatus(message, isSuccess) {
            const statusEl = document.getElementById('status');
            statusEl.textContent = message;
            statusEl.style.display = 'block';
            
            if (isSuccess) {
                statusEl.className = 'status success';
            } else {
                statusEl.className = 'status error';
            }
            
            // 滚动到状态消息
            statusEl.scrollIntoView({ behavior: 'smooth' });
        }
    </script>
</body>
</html>
'@
    
    # 确保 static 目录存在
    if (-not (Test-Path "static")) {
        New-Item -Path "static" -ItemType Directory -Force | Out-Null
    }
    
    # 写入 HTML 文件
    Set-Content -Path "static/index.html" -Value $htmlContent
}

# 启动一个简单的HTTP服务器来提供前端页面
function Start-DeployServer {
    Write-Host "正在启动部署服务器..."
    
    # 创建一个临时的Node.js服务器
    $serverCode = @'
const http = require('http');
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const url = require('url');

const PORT = 3000;

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    
    // 处理静态文件请求
    if (req.method === 'GET' && parsedUrl.pathname === '/') {
        fs.readFile('./static/index.html', (err, data) => {
            if (err) {
                res.writeHead(500);
                res.end('Error loading the page');
                console.error('Error reading file:', err);
                return;
            }
            
            res.writeHead(200, { 'Content-Type': 'text/html' });
            res.end(data);
        });
        return;
    }
    
    // 处理健康检查
    if (req.method === 'GET' && parsedUrl.pathname === '/health') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ status: 'ok', timestamp: new Date().toISOString() }));
        return;
    }
    
    // 处理部署请求
    if (req.method === 'POST' && parsedUrl.pathname === '/deploy') {
        let body = '';
        
        req.on('data', chunk => {
            body += chunk.toString();
        });
        
        req.on('end', () => {
            try {
                const data = JSON.parse(body);
                const { domain, gitrepo, command } = data;
                
                // 参数验证
                if (!gitrepo || !command) {
                    res.writeHead(400, { 'Content-Type': 'application/json' });
                    res.end(JSON.stringify({ success: false, error: 'Gitee项目和运行命令是必填的' }));
                    return;
                }
                
                console.log(`[${new Date().toISOString()}] 开始部署:`, data);
                fs.appendFileSync('deploy.log', `[${new Date().toISOString()}] 开始部署: ${JSON.stringify(data)}\n`);
                
                // 处理仓库URL，提取仓库名
                let repoPath = gitrepo;
                if (repoPath.startsWith('https://gitee.com/') || repoPath.startsWith('http://gitee.com/')) {
                    repoPath = repoPath.replace(/^https?:\/\/gitee\.com\//, '');
                }
                const repoName = repoPath.split('/').pop();
                
                // 项目将部署到 /projects/仓库名 目录
                const projectFolder = path.join('/projects', repoName);
                
                // 构建部署命令
                const deployScript = `
                # 确保 /projects 目录存在
                if (-not (Test-Path "/projects")) {
                    New-Item -Path "/projects" -ItemType Directory -Force
                }

                # 创建或进入项目目录
                if (-not (Test-Path "${projectFolder}")) {
                    New-Item -Path "${projectFolder}" -ItemType Directory -Force
                }
                Set-Location "${projectFolder}"
                
                # 克隆或更新仓库
                if (-not (Test-Path ".git")) {
                    git clone https://gitee.com/${repoPath} .
                } else {
                    git pull
                }
                
                # 保存域名配置（如果提供）
                if ("${domain}") {
                    "域名: ${domain}" | Out-File -FilePath "config.txt" -Encoding utf8
                }
                
                # 执行用户指定的命令
                ${command}
                `;
                
                // 将脚本写入临时文件
                fs.writeFileSync('temp_deploy.ps1', deployScript, 'utf8');
                
                // 执行部署脚本
                exec('powershell -ExecutionPolicy Bypass -File temp_deploy.ps1', (error, stdout, stderr) => {
                    // 删除临时脚本文件
                    try {
                        fs.unlinkSync('temp_deploy.ps1');
                    } catch (e) {
                        console.error('无法删除临时脚本文件:', e);
                    }
                    
                    let output = stdout + (stderr ? '\n错误输出:\n' + stderr : '');
                    fs.appendFileSync('deploy.log', `[${new Date().toISOString()}] 部署结果:\n${output}\n`);
                    
                    if (error) {
                        console.error(`[${new Date().toISOString()}] 部署错误:`, error);
                        fs.appendFileSync('deploy.log', `[${new Date().toISOString()}] 部署错误: ${error}\n`);
                        
                        res.writeHead(500, { 'Content-Type': 'application/json' });
                        res.end(JSON.stringify({
                            success: false,
                            error: error.message,
                            output: output
                        }));
                    } else {
                        console.log(`[${new Date().toISOString()}] 部署成功`);
                        fs.appendFileSync('deploy.log', `[${new Date().toISOString()}] 部署成功\n`);
                        
                        res.writeHead(200, { 'Content-Type': 'application/json' });
                        res.end(JSON.stringify({
                            success: true,
                            output: output,
                            project_path: projectFolder
                        }));
                    }
                });
                
            } catch (e) {
                console.error(`[${new Date().toISOString()}] 解析请求错误:`, e);
                fs.appendFileSync('deploy.log', `[${new Date().toISOString()}] 解析请求错误: ${e}\n`);
                
                res.writeHead(400, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({
                    success: false,
                    error: '无效请求格式'
                }));
            }
        });
        
        return;
    }
    
    // 处理404
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
});

server.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
    console.log(`请访问 http://localhost:${PORT} 来使用部署工具`);
});
'@

    # 将服务器代码保存到文件
    Set-Content -Path "server.js" -Value $serverCode
    
    # 启动Node.js服务器
    Start-Process -FilePath "node" -ArgumentList "server.js" -NoNewWindow
    
    Write-Host "部署服务器已启动，请访问: http://localhost:$SERVER_PORT"
    Write-Host "按 Ctrl+C 退出脚本，服务器将继续在后台运行"
    
    # 打开浏览器访问部署页面
    Start-Process "http://localhost:$SERVER_PORT"
}

# 主函数
function Start-Main {
    Write-Host "===== Gitee项目一键部署工具 v1.0 ====="
    Write-Host "此工具将帮助你从Gitee仓库部署项目到服务器"
    
    Check-Dependencies
    Generate-FrontendHTML
    Start-DeployServer
    
    # 保持脚本运行，除非用户按Ctrl+C退出
    try {
        Write-Host "服务器正在运行中，按 Ctrl+C 退出..."
        while ($true) {
            Start-Sleep -Seconds 1
        }
    } 
    finally {
        Write-Host "脚本已退出，但服务器可能仍在后台运行"
    }
}

# 执行主函数
Start-Main 